<?php

require_once "tfsbox.class.php";
require_once "tfsbox_control_panel_view.class.php";

class TFsBOXControlPanel extends TFsBOX
	{
		function __construct($config_log = null,
							 $shouts_log = null,
							 $ip_log = null,
							 $url_log = null,
							 $wordfilters_log = null,
							 $config_obj = null,
							 $db_obj = null,
							 $sess_obj = null)
			{
				parent::__construct($config_log,
									$shouts_log,
									$ip_log,
									$url_log,
									$wordfilters_log,
									$config_obj,
									$db_obj,
									$sess_obj,
									'TFsBOXControlPanelView');

				if (self::$Database->databaseMode()
				 && is_writable("mysql/db.php")
				 && self::$Session->userRanking() == TFsBOXSession::ADMIN)
					self::$Session->storeNotice("The file <tt>db.php</tt> is writable; you should chmod it back to 0644.");
			}

		function parsePathInfo()
			{
				if (!self::$Session->loggedIn())
					TFsBOX::redirect($_SERVER['SCRIPT_NAME']."/tfsbox/login");

				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/mysql")
				{
					TFsBOXSession::storeNotice("This is for those whose server supports MySQL and want to have ". TFsBOX::Name ." make use of a MySQL database instead of relying on flatfiles. Do not attempt to install if you are unfamiliar with databases.");
					if (!is_writable("mysql/db.php"))
						TFsBOXSession::storeError("The file <tt>db.php</tt> is not writable.");
				}

				// Add word filter
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/filters/add/word_filter")
				{
					self::$Database->addWordFilter($_POST['tfsbox_new_word_filter'][0],
												   $_POST['tfsbox_new_word_filter'][1]);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/filters');
				}

				// Clear reports
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/reports/clear")
				{
					self::$Database->clearReports();
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] . '/tfsbox/cpanel');
				}

				// Clear shouts
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/shouts/clear")
				{
					self::$Database->clearShouts();
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] . '/tfsbox/cpanel');
				}

				// Edit shout
				if (TFsBOX::pathInfo() == '/tfsbox/cpanel/shouts/edit')
				{
					if ($_POST['tfsbox_shout_id'] > -1)
					{
						// Assume user has requested to edit shout
						if (empty($_POST['tfsbox_shout']))
						{
							// Retrieve shout
							echo htmlentities(self::$Database->shout($_POST['tfsbox_shout_id']));
							exit(); // Prevent other data from rendering
						}

						// Assume user has finished editing shout
						else
							self::$Database->editShout($_POST['tfsbox_shout_id']);

						TFsBOX::redirect($_SERVER['SCRIPT_NAME'] . '/tfsbox/cpanel/shoutbox');
					}
				}

				// Delete shout
				if (preg_match("#^/tfsbox/cpanel/shouts/delete/\d+#", TFsBOX::pathInfo()))
				{
					$id = (int) TFsBOXSession::$PathInfo[count(TFsBOXSession::$PathInfo)-1];
					self::$Database->deleteShout($id);

					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] . '/tfsbox/cpanel/shoutbox');
				}

				// Remove IP
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/filters/remove/ip")
				{
					self::$Database->removeIps($_POST['tfsbox_unban_ips']);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/filters');
				}

				// Remove URL
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/filters/remove/url")
				{
					self::$Database->removeUrls($_POST['tfsbox_unban_urls']);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/filters');
				}

				// Remove word filter
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/filters/remove/word_filter")
				{
					self::$Database->removeWordFilters($_POST['tfsbox_remove_word_filter']);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/filters');
				}

				// Unsubscribe
				if (preg_match("#^/tfsbox/cpanel/unsubscribe/#", TFsBOX::pathInfo()))
				{
					$sub = TFsBOXSession::$PathInfo[count(TFsBOXSession::$PathInfo)-1];
					self::$Database->unsubscribe(self::$Session->userId(), $sub);
					$redirect = (self::$Session->userRanking() == TFsBOXSession::ADMIN) ? "/subscriptions" : "";
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel'. $redirect);
				}

				// Promote user
				if (preg_match("#^/tfsbox/cpanel/users/promote/#", TFsBOX::pathInfo()))
				{
					$id = (int) TFsBOXSession::$PathInfo[count(TFsBOXSession::$PathInfo)-1];
					self::$Database->promoteUser($id);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/users');
				}

				// Demote user
				if (preg_match("#^/tfsbox/cpanel/users/demote/#", TFsBOX::pathInfo()))
				{
					$id = (int) TFsBOXSession::$PathInfo[count(TFsBOXSession::$PathInfo)-1];
					self::$Database->demoteUser($id);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/users');
				}

				// Update user site
				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/update_site")
				{
					self::$Database->setUserSite(self::$Session->userId(), $_POST['tfsbox_site']);
					TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel');
				}

				if (TFsBOX::pathInfo() == "/tfsbox/cpanel/update_password")
				{
				}

				// MySQL Setup
				if (self::$Session->userRanking()
				 == TFsBOXSession::ADMIN)
				{
					if (!self::$Database->databaseMode()
					 && TFsBOX::pathInfo() == "/tfsbox/cpanel/mysql/install")
					{
						if ((empty($_POST['tfsbox_db_host'])
						 || empty($_POST['tfsbox_db_shoutbox_admin_user'])
						 || empty($_POST['tfsbox_db_user'])
						 || empty($_POST['tfsbox_db_shoutbox_admin_pass'])
						 || empty($_POST['tfsbox_db_pass'])
						 || empty($_POST['tfsbox_db_shoutbox_admin_email'])
						 || empty($_POST['tfsbox_db_name'])
						 || empty($_POST['tfsbox_db_prefix'])
						 || empty($_POST['tfsbox_shoutbox_path'])
						 || empty($_POST['tfsbox_verification_method'])
						 || empty($_POST['tfsbox_max_login_attempts'])
						 || empty($_POST['tfsbox_allow_guests']))
						 && $_POST['tfsbox_max_login_attempts'] != "0")
							TFsBOXSession::storeError("You did not fill in all fields; all fields are required.");
						else if ($_POST['tfsbox_max_login_attempts'] == "0")
							TFsBOXSession::storeError("Maximum login attempts must be greater than 0.");
						else
						{
							self::$Database->setDatabaseMode(TFsBOXDatabase::MYSQL);
							self::$Database->connectToMysql($_POST['tfsbox_db_host'],
															$_POST['tfsbox_db_user'],
															$_POST['tfsbox_db_pass']);
							$this->setupMysqlDatabase();
							self::$Database->setDatabaseMode(TFsBOXDatabase::FLATFILE);
						}
					}

					// Shoutbox settings
					if (TFsBOX::pathInfo() == "/tfsbox/cpanel/shoutbox/settings")
					{
						// Shouts per page
						if ($_POST['tfsbox_shouts_per_page'] > 0)
							self::$Config->setValue("shouts_per_page", (int) $_POST['tfsbox_shouts_per_page']);
						else if (isset($_POST['tfsbox_shouts_per_page']))
							TFsBOXSession::storeError("Shouts per page must be a number and greater than 0.");

						// Form menu display
						if (preg_match("#^click|hover$#", $_POST['tfsbox_form_menu_display']))
							self::$Config->setValue("form_menu_display", $_POST['tfsbox_form_menu_display']);
						else if (isset($_POST['tfsbox_form_menu_display']))
							TFsBOXSession::storeError("Invalid value for form menu display.");

						// Allow images
						if (preg_match("#^yes|no$#", $_POST['tfsbox_allow_images']))
							self::$Config->setValue("allow_images", $_POST['tfsbox_allow_images']);
						else if (isset($_POST['tfsbox_allow_images']))
							TFsBOXSession::storeError("Invalid value for allow images.");

						// Name length
						if ($_POST['tfsbox_name_length'] > 0)
							self::$Config->setValue("name_length", (int) $_POST['tfsbox_name_length']);
						else if (isset($_POST['tfsbox_name_length']))
							TFsBOXSession::storeError("Name length must be a number and greater than 0.");

						// Site URL
						if (isset($_POST['tfsbox_site_url']))
						{
							if (preg_match(TFsBOX::SiteRegex, $_POST['tfsbox_site_url']))
								self::$Config->setValue("site_url", $_POST['tfsbox_site_url']);
							else
								TFsBOXSession::storeError("Invalid URL for site URL.");
						}

						// Form position
						if (preg_match("#^top|left|bottom|right$#", $_POST['tfsbox_form_position']))
							self::$Config->setValue("form_position", $_POST['tfsbox_form_position']);
						else if (isset($_POST['tfsbox_form_position']))
							TFsBOXSession::storeError("Invalid value for form position.");

						// Database type
						if (preg_match("#^flatfile|mysql$#", $_POST['tfsbox_db_type']))
							self::$Config->setValue("db_type", $_POST['tfsbox_db_type']);
						else if (isset($_POST['tfsbox_db_type']))
							TFsBOXSession::storeError("Invalid value for database mode.");

						// Anti-spam timeout
						if ($_POST['tfsbox_antispam_timeout'] > 0)
							self::$Config->setValue("antispam_timeout", (int) $_POST['tfsbox_antispam_timeout']);
						else if (isset($_POST['tfsbox_antispam_timeout']))
							TFsBOXSession::storeError("Anti-spam timeout must be a number and greater than 0.");

						// Smiley pack
						if (is_dir($_POST['tfsbox_smiley_pack'])
						 && !empty($_POST['tfsbox_smiley_pack']))
							self::$Config->setValue("smiley_pack", $_POST['tfsbox_smiley_pack']);
						else if (isset($_POST['tfsbox_smiley_pack']))
							TFsBOXSession::storeError("Invalid path for smiley pack.");

						if (!self::$Session->hasErrors())
							TFsBOX::redirect($_SERVER['SCRIPT_NAME'] .'/tfsbox/cpanel/shoutbox');
					}
				}
			}

		function renderControlPanel()
			{
				TFsBOXAbstractView::renderShoutBoxTitleBar();

				if (self::$Session->loggedIn())
				{
					if (self::$Session->hasErrors())
						TFsBOXAbstractView::renderErrors();

					if (self::$Session->hasNotices())
						TFsBOXAbstractView::renderNotices();

					// Flatfile
					if (!self::$Database->databaseMode())
						self::$View->renderControlPanel();

					// MySQL
					else
					{
						if (self::$Session->userRanking()
						 == TFsBOXSession::ADMIN)
							self::$View->renderControlPanel();
						else
							self::$View->renderUserPanel();
					}
				}
			}

		private function setupMysqlDatabase()
			{
				if (self::$Database->databaseConnection())
				{
					define("TFsBOX_DB_HOST", $_POST['tfsbox_db_host']);
					define("TFsBOX_DB_USER", $_POST['tfsbox_db_user']);
					define("TFsBOX_DB_PASS", $_POST['tfsbox_db_pass']);
					define("TFsBOX_DB_NAME", $_POST['tfsbox_db_name']);
					define("TFsBOX_DB_PREFIX", $_POST['tfsbox_db_prefix']);

					$shout_sql = "`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,"
								."`user_id` INT UNSIGNED NOT NULL ,"
								."`ip` INT UNSIGNED NOT NULL ,"
								."`name` VARCHAR( 255 ) NULL ,"
								."`shout` TEXT NOT NULL ,"
								."`site` TEXT NULL ,"
								."`date` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,"
								."`report` BOOL NOT NULL DEFAULT  '0'";

					self::$Database->createTable($shout_sql,
												 TFsBOX_DB_PREFIX ."shouts",
												 TFsBOX_DB_NAME);

					$users_sql = "`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,"
								."`username` VARCHAR( 255 ) NOT NULL ,"
								."`password` VARCHAR( 255 ) NOT NULL ,"
								."`email` VARCHAR( 255 ) NOT NULL ,"
								."`site` VARCHAR( 255 ) NULL ,"
								."`verified` BOOL NULL DEFAULT  '0',"
								."`ranking` TINYINT( 1 ) UNSIGNED NULL DEFAULT  '3',"
								."`login_attempts` TINYINT( 1 ) UNSIGNED NULL DEFAULT  '0',"
								."`last_login_attempt` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ,"
								."`login_ips` TEXT NULL ,"
								."`banned` BOOL NULL DEFAULT  '0',"
								."`auth_token` VARCHAR( 255 ) NULL ,"
								."`form_position` VARCHAR( 6 ) NULL DEFAULT  'bottom',"
								."`reset_password` VARCHAR( 255 ) NULL,"
								."`subscriptions` TEXT NOT NULL";

					if (self::$Database->createTable($users_sql,
													 TFsBOX_DB_PREFIX ."users",
													 TFsBOX_DB_NAME))
					{
						if (self::$Database->addUser($_POST['tfsbox_db_shoutbox_admin_user'],
													 $_POST['tfsbox_db_shoutbox_admin_pass'],
													 $_POST['tfsbox_db_shoutbox_admin_email'],
													 TFsBOX_SITE))
						{
							self::$Database->approveUser(1);
							self::$Database->promoteUser(1, TFsBOXSession::ADMIN);
						}
					}

					$settings_sql = "`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,"
								   ."`shoutbox_path` TINYTEXT NOT NULL ,"
								   ."`verification_method` VARCHAR( 6 ) NOT NULL DEFAULT  'email',"
								   ."`max_login_attempts` TINYINT( 1 ) UNSIGNED NOT NULL DEFAULT  '5',"
								   ."`allow_guests` BOOL NOT NULL DEFAULT  '0'";

					if (self::$Database->createTable($settings_sql,
													 TFsBOX_DB_PREFIX . "settings",
													 TFsBOX_DB_NAME))
					{
						$sql_add_settings = "INSERT INTO ". TFsBOX_DB_PREFIX ."settings "
										   ."(`id`, `shoutbox_path`, `verification_method`, `max_login_attempts`, `allow_guests`) "
										   ."values "
										   ."(NULL, 'http://". $_SERVER['SERVER_NAME'] . dirname($_SERVER['SCRIPT_NAME']). "/', 'email', '5', '0')";
						if (mysql_query($sql_add_settings))
						{
							self::$Database->adjustSettings($_POST['tfsbox_shoutbox_path'],
															$_POST['tfsbox_verification_method'],
															$_POST['tfsbox_max_login_attempts'],
															$_POST['tfsbox_allow_guests']);
						}

						else TFsBOXSession::storeError("Could not insert additional settings: ". mysql_errno() .": ". mysql_error());
					}

					// Attempt to make an atomic installation
					if (self::$Session->hasErrors())
					{
						self::$Database->dropTable(TFsBOX_DB_PREFIX ."shouts", TFsBOX_DB_NAME);
						self::$Database->dropTable(TFsBOX_DB_PREFIX ."users", TFsBOX_DB_NAME);
						self::$Database->dropTable(TFsBOX_DB_PREFIX ."settings", TFsBOX_DB_NAME);
					}

					else
					{
						$db_file_contents = '<?php'."\n\n"
										   .'define("TFsBOX_DB_HOST", "'.$_POST['tfsbox_db_host'].'");'."\n"
										   .'define("TFsBOX_DB_USER", "'.$_POST['tfsbox_db_user'].'");'."\n"
										   .'define("TFsBOX_DB_PASS", "'.$_POST['tfsbox_db_pass'].'");'."\n"
										   .'define("TFsBOX_DB_NAME", "'.$_POST['tfsbox_db_name'].'");'."\n"
										   .'define("TFsBOX_DB_PREFIX", "'.$_POST['tfsbox_db_prefix'].'");'."\n\n"
										   .'?>';
						file_put_contents("mysql/db.php", $db_file_contents);
						self::$Config->setValue("db_type", "mysql");
					}
				}

				else TFsBOXSession::storeError("No database connection could be initiated.");
			}
	}

?>
